using System.Collections.Generic;
using Tycho.Runtime;
using Goletas.Collections;

namespace Tycho.PerformanceTests {
    public class Frames {
        [BenchMark]
        public static void DictionaryFrame () {
            Dictionary<AnyObject, AnyObject> frame = new Dictionary<AnyObject, AnyObject>();

            frame [Symbols.RuntimePlus] = 10;
            frame [Symbols.RuntimeMinus] = 20;
            frame [Symbols.RuntimeMultiply] = 30;
            frame [Symbols.RuntimeDivide] = 40;
            frame [Symbols.RuntimeString] = 50;
            frame [Symbols.RuntimeInteger] = 60;
            frame [Symbols.RuntimeReal] = 70;
            frame [Symbols.RuntimeBoolean] = 80;

            for (int n = 0; n < 1000000; n++) {
                frame [Symbols.RuntimePlus] = frame [Symbols.RuntimeString];
                frame [Symbols.RuntimeMinus] = frame [Symbols.RuntimeInteger];
                frame [Symbols.RuntimeMultiply] = frame [Symbols.RuntimeReal];
                frame [Symbols.RuntimeDivide] = frame [Symbols.RuntimeBoolean];
            }
        }

        [BenchMark]
        public static void Array () {
            AnyObject[] frame = new AnyObject[8];

            int i = 0;
            frame [i++] = 10;
            frame [i++] = 20;
            frame [i++] = 30;
            frame [i++] = 40;
            frame [i++] = 50;
            frame [i++] = 60;
            frame [i++] = 70;
            frame [i++] = 80;

            for (int n = 0; n < 1000000; n++) {
                frame [0] = frame [4];
                frame [1] = frame [5];
                frame [2] = frame [6];
                frame [3] = frame [7];
            }
        }

        [BenchMark]
        public static void ArrayFrameObject () {
            ArrayFrameObject frameObject = new ArrayFrameObject (8);

            int i = 0;
            frameObject [i++] = 10;
            frameObject [i++] = 20;
            frameObject [i++] = 30;
            frameObject [i++] = 40;
            frameObject [i++] = 50;
            frameObject [i++] = 60;
            frameObject [i++] = 70;
            frameObject [i++] = 80;

            for (int n = 0; n < 1000000; n++) {
                frameObject [0] = frameObject [4];
                frameObject [1] = frameObject [5];
                frameObject [2] = frameObject [6];
                frameObject [3] = frameObject [7];
            }
        }

        [BenchMark]
        public static void GoletasSortedDictionaryAsArray () {
            Goletas.Collections.SortedDictionary<int, int> frame = new Goletas.Collections.SortedDictionary<int, int> ();

            int i = 0;
            frame [i++] = 10;
            frame [i++] = 20;
            frame [i++] = 30;
            frame [i++] = 40;
            frame [i++] = 50;
            frame [i++] = 60;
            frame [i++] = 70;
            frame [i++] = 80;

            for (int n = 0; n < 1000000; n++) {
                frame [0] = frame [4];
                frame [1] = frame [5];
                frame [2] = frame [6];
                frame [3] = frame [7];
            }
        }
    }

    class ArrayFrameObject : SimpleObject {
        private AnyObject[] Frame;

        public ArrayFrameObject (int capacity) {
            Frame = new AnyObject[capacity];
        }

        public override AnyObject this [AnyObject n] {
            get {
                return Frame [(int) n];
            }
            set {
                Frame [(int) n] = value;
            }
        }
    }
}
